/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bff.spi.defaultvalue;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.inspur.edp.bff.api.exception.BffFrameworkException;
import com.inspur.edp.bff.api.exception.ErrorCodes;
import com.inspur.edp.bff.api.manager.IFSManager;
import com.inspur.edp.bff.api.manager.IFSManagerFactory;
import com.inspur.edp.bff.entity.defaultvalue.VoDefaultValue;
import com.inspur.edp.bff.spi.utils.VoJsonDeserializer;
import com.inspur.edp.cef.spi.jsonser.base.StringUtils;
import io.iec.edp.caf.runtime.config.CefBeanUtil;

import java.io.IOException;
import java.lang.reflect.Method;

public abstract class VoDefaultValueDeserializer extends VoJsonDeserializer<VoDefaultValue> {

    private Class entityType;
    private IFSManagerFactory fsMgrFactory;

    protected VoDefaultValueDeserializer() {
        entityType = getManager().createData().getClass();
    }

    @Override
    public VoDefaultValue deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
            throws IOException, JsonProcessingException {

        VoDefaultValue defaultValue = createDefaultValue();
        if (jsonParser.getCurrentToken() != JsonToken.START_OBJECT) {
            throw new BffFrameworkException(ErrorCodes.BFF_FRAMEWORK_0001);
        }
        //reader.Read();
        jsonParser.nextToken();
        while (jsonParser.getCurrentToken() == JsonToken.FIELD_NAME)//reader.Read())
        {

            if (jsonParser.getCurrentToken() == JsonToken.END_OBJECT) {
                break;
            }
            String propertyName = jsonParser.getValueAsString();//(String)reader.getValue();
            jsonParser.nextToken();
            ;//reader.Read();
            readPropertyDefaultValue(jsonParser, deserializationContext, defaultValue, propertyName);
            jsonParser.nextToken();
        }
        return defaultValue;
    }

    private void readPropertyDefaultValue(JsonParser jsonParser, DeserializationContext deserializationContext, VoDefaultValue defaultValue, String propertyName) throws IOException {
//        Object value = jsonParser.getCurrentValue();//reader.getValue();
//        if (jsonParser.getCurrentToken()== JsonToken.START_OBJECT)
//        {
//            ObjectMapper mapper = new ObjectMapper();
//            value = mapper.readValue(jsonParser, JsonNode.class);
//            readObject(jsonParser);
//        }

        Object transValue = getDefaultValue(propertyName, jsonParser);

        defaultValue.getDefaultValue().put(getPropertyName(entityType, propertyName), transValue);
    }

    private String getPropertyName(Class entityType, String propertyName) {
        if (!propertyName.equals(StringUtils.toCamelCase(propertyName))) {
            return propertyName;
        }

        Method[] methods = entityType.getMethods();
        for (Method method : methods) {
            JsonProperty annotation = method.getAnnotation(JsonProperty.class);
            if (annotation == null)
                continue;
            if (!method.getName().startsWith("get"))
                continue;
            String propName = method.getName().substring(3, method.getName().length());
            if (propertyName.equals(StringUtils.toCamelCase(propName)) || propertyName.equals(propName)) {
                return propName;
            }
        }

        return propertyName;
    }

    private void readObject(JsonParser reader) throws IOException {
        if (reader.getCurrentToken() == JsonToken.START_OBJECT) {
            reader.nextToken();
        }
        while (reader.getCurrentToken() == JsonToken.FIELD_NAME) {
            reader.nextToken();
            reader.nextToken();
        }
    }

    /**
     * 创建对象实例方法，用来创建Vo默认值实例。
     *
     * @return 得到的Vo默认值实例<see cref = " VoDefaultValue " />
     */
    protected abstract VoDefaultValue createDefaultValue();

    private IFSManagerFactory getFsMgrFactory() {
        if (fsMgrFactory == null) {
            fsMgrFactory = CefBeanUtil.getAppCtx().getBean(IFSManagerFactory.class);
        }
        return fsMgrFactory;
    }

    private IFSManager getManager() {
        return getFsMgrFactory().getFSManager(getFSType());
    }
    //TODO这个地方临时使用，需要尽快抽取到VM的转换器里面。

    /**
     * 获取VM的类型。
     *
     * @return 得到的VM类型。
     */
    protected abstract String getFSType();

    protected abstract Object getDefaultValue(String propertyName, Object propertyValue);
}
